package main

import (
	"os/exec"
	"log"
	"time"
	"fmt"
	"bufio"

	"strings"
	"bytes"
	"errors"

	"github.com/nats-io/nats.go"
)

var AlertPhone = ""
var NatsUrl = ""
var NatsToken = ""

// curl test: curl -X POST http://127.0.0.1:8080/papergold
func runCommand(cmdStr string, argStr ...string) (bytes.Buffer, error) {
    cmd := exec.Command(cmdStr, argStr...)
    var out bytes.Buffer
    cmd.Stdout = &out

    err := cmd.Run()
    if err != nil {
	    fmt.Println("command exeute error:", err)
	    return out, err
    }
    return  out, nil
}

func getDevice() error {
    out, err := runCommand("adb", "devices")
    if err != nil {
	fmt.Println("get device error")
    	return errors.New("no device")
    }
    if strings.Contains(out.String(), "device\n") {
       return nil
    }
    return errors.New("no device")
}

func isOnCalling() (bool, error) {
    out, err := runCommand("adb", "shell", "dumpsys", "telephony.registry")
    if err != nil {
       fmt.Println("get call state error")
       return false, errors.New("get call state error")
    }

    scanner := bufio.NewScanner(&out)
    for scanner.Scan() {
	if strings.Contains(scanner.Text(), "mCallState=2") {
	  return true, nil
	}
    }
    return false, nil
}

func call(phone string) error{
	_, err := runCommand("adb", "shell", "am", "start", "-a", "android.intent.action.CALL", "tel:" + phone)
	if err != nil {
           fmt.Println("call error")
	   return err
	}
	return nil
}

func stopCall() {
    _, _ = runCommand("adb", "shell", "input", "keyevent", "KEYCODE_ENDCALL")
}

func main() {
	nc, err := nats.Connect("tls://"+NatsUrl,
		nats.Timeout(time.Second*2),
		nats.NoEcho(),
		nats.Token(NatsToken),
		nats.MaxReconnects(-1),
	)
	if err != nil {
		log.Fatalf("nats connect: %v\n", err)
	}
	log.Println("connected to nats queue")

	msg_in := make(chan *nats.Msg, 64)
	_, err = nc.ChanSubscribe("papergold", msg_in)
	if err != nil {
		log.Fatalf("channel subsribe: %v", err)
	}

	go func(in chan *nats.Msg) {
	   for _ = range in {
	      if err := getDevice(); err != nil {
		fmt.Println("error", err)
		continue
	      }
	      if isOnCall, err := isOnCalling(); err != nil {
		fmt.Println("error", err)
		continue
	      } else if isOnCall {
		 stopCall()
		 time.Sleep(2 * time.Second)
		 call(AlertPhone)
	      } else {
		  call(AlertPhone)
	      }
	   }
	}(msg_in)

	select {}
}

